/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.just.dusin.ooii.component.kj;

import gnu.io.CommPortIdentifier;
import gnu.io.NoSuchPortException;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
import gnu.io.UnsupportedCommOperationException;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import org.apache.log4j.Logger;
import org.dusin.array.util.ArrayUtil;
import org.dusin.comm.util.PrimaryNumber2Bytes;
import org.dusin.verify.CRC16;


/**
 *
 * @author Admin
 */
public class SkeCollector extends Collector{
    private static Logger logger = Logger.getLogger(SkeCollector.class.getName());
    private final int READ_DATA_LENGTH=27;
    private final int MAX_DATA_LENGTH=100;
     public Map<String,Object> retrieve() {        
        Map<String,Object> valueMap = new HashMap<String,Object>();        
        try {
            commPortId = CommPortIdentifier.getPortIdentifier(portId);
            serialPort = (SerialPort) commPortId.open("OOII", 2000);
            outputStream = serialPort.getOutputStream();
            inputStream = serialPort.getInputStream();

            serialPort.setSerialPortParams(9600,
                    SerialPort.DATABITS_8,
                    SerialPort.STOPBITS_1,
                    SerialPort.PARITY_NONE);
            
            byte[] readBuffer;
            

            byte[] readCommand = new byte[]{(byte) address, (byte) 0x06, (byte) 01, (byte) 06, (byte) 0x00, (byte) 0xff,0x0,0x0};
            CRC16 crc = new CRC16();
            crc.update(readCommand, 0, readCommand.length-2);
            readCommand[readCommand.length-1]=crc.getMSB();
            readCommand[readCommand.length-2]=crc.getLSB();
            outputStream.write(readCommand);

            Thread.sleep(delay);
            readBuffer = new byte[this.MAX_DATA_LENGTH];
            
            if (inputStream.available() > 0) {                    
                int numBytes = inputStream.read(readBuffer);
                //System.out.println();
                if(numBytes==this.READ_DATA_LENGTH&&crc.verify(readBuffer)){
                    double currentTotal = getTotal(readBuffer);
                    double flowSpeed = getFlowSpeed(readBuffer);
                    double beltSpeed=getBeltSpeed(readBuffer);
                    byte shellOpen = 0;
                    if(Math.abs(preTotal+1)<1e-6||Math.abs(currentTotal-preTotal)<60) { //对获取的数据进行监测
                        
                        valueMap.put("no", no);
                        valueMap.put("currentTotal", currentTotal);
                        valueMap.put("flowSpeed", flowSpeed);
                        valueMap.put("beltSpeed", beltSpeed);
                        valueMap.put("shellOpen",shellOpen);
                        valueMap.put("type", 0);                        
                        preTotal= currentTotal;
                        addQueue(0);
                    }
                    else{
                        //3表示有回应27字节数据，但数据异常
                        valueMap.put("no", no);
                        valueMap.put("currentTotal", 0.0);
                        valueMap.put("flowSpeed", 0.0);
                        valueMap.put("beltSpeed", 0.0);
                        valueMap.put("shellOpen",new Byte((byte)0));
                        valueMap.put("type", 3);                        
                        addQueue(1);
                    }
                }else{
                    //2表示有回应数据，但数据不足92字节，或不能通过校验码
                    valueMap.put("no", no);
                    valueMap.put("currentTotal", 0.0);
                    valueMap.put("flowSpeed", 0.0);
                    valueMap.put("beltSpeed", 0.0);
                    valueMap.put("shellOpen",new Byte((byte)0));
                    valueMap.put("type", 2);                        
                    addQueue(1);
                    logger.error("仪表数据异常，数据不足27字节，或不能通过校验码");
                }                        
            }else{                    
                //1表示指令发送，设备无响应
                valueMap.put("no", no);
                valueMap.put("currentTotal", 0.0);
                valueMap.put("flowSpeed", 0.0);
                valueMap.put("beltSpeed", 0.0);
                valueMap.put("shellOpen",new Byte((byte)0));
                valueMap.put("type", 1);                        
                addQueue(1);
                logger.error("指令发送，设备无响应");
            }
        } catch (PortInUseException ex) {
            logger.error("该端口被占用");
        } catch (NoSuchPortException ex) {
            logger.equals("该端口不存在");
        } catch (IOException e) {
            logger.error("IO异常:" + e.getMessage());
        } catch (InterruptedException e) {
            logger.warn("sleep被中断");
        } catch (UnsupportedCommOperationException e) {
            logger.error("不支持操作:" + e.getMessage());
        } finally {           
            try {
                if(inputStream!=null)
                    inputStream.close();
                if(outputStream!=null)
                    outputStream.close();
                if(serialPort!=null)
                    serialPort.close();            
            } catch (IOException ex) {
                logger.error("IO异常：" + ex.getMessage());
            }
        }
        return valueMap;
    }

    private double getTotal(byte[] readBuffer) {
         byte[] totalBytes = Arrays.copyOfRange(readBuffer, 17, 21);
        System.out.println(totalBytes.length);
        ArrayUtil.reverse(totalBytes);
        double total=PrimaryNumber2Bytes.getInt(totalBytes, 0)/1000.0;
        return total;
    }

    private double getFlowSpeed(byte[] readBuffer) {
        byte[] flowBytes = Arrays.copyOfRange(readBuffer, 13, 17);
        ArrayUtil.reverse(flowBytes);
        double flow=PrimaryNumber2Bytes.getFloat(flowBytes, 0);
        return flow;
    }

    private double getBeltSpeed(byte[] readBuffer) {
         byte[] speedBytes = Arrays.copyOfRange(readBuffer, 9, 13);
        ArrayUtil.reverse(speedBytes);
        double speed = PrimaryNumber2Bytes.getFloat(speedBytes, 0);
        return speed;
    }
    
}
